<template>
  <div class="spec-config" :id="comId">
    <!--    spu参数配置-规格配置-->
    <div
      v-for="(spec, index) in specList"
      :key="spec.id"
      :style="{
        'margin-top': ifChild ? '0' : '10px',
        'margin-bottom': ifChild ? '10px' : 0,
      }"
    >
      <!--      规格项(属性)的展示-->
      <template v-if="spec.type === SpuSpecificationTypeEnum.ATTR">
        <!--        基础信息-->
        <SpecBasicInfo
          ref="specBasicInfoRef"
          :spec-item="spec"
          :cur-index="index"
          @remove="handleRemoveSpecItem(index)"
          @choose-ok="(data) => handleChooseBizMetaAttrOk(data, index)"
        />
        <!--        规格配置-->
        <SpecConfig
          style="margin-bottom: 10px"
          :spec-item="spec"
          @choose-ok="(data) => handleChooseOptValueOk(data, index)"
        />
      </template>
      <!--      规格组展示-->
      <template v-else>
        <SpecGroup
          ref="specGroupRef"
          :spec-item="spec"
          @remove="handleRemoveGroup(index)"
          @add-spec="(type) => handleAddSpecInGroup(type, index)"
          @relevance-opr-value="(data) => handleRelevanceOprValue(data, spec)"
          @choose-biz-meta-attr="(data) => handleChooseGroupBizMetaAttr(data, index)"
        />
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
  import Sortable from 'sortablejs';
  import { cloneDeep, debounce } from 'lodash-es';
  import { defaultSpuSpec } from '@/views/spu/spu/setting/data';
  import { computed, inject, nextTick, onMounted, ref } from 'vue';
  import SpecGroup from '@/views/spu/spu/setting/components/SpecGroup.vue';
  import SpecConfig from '@/views/spu/spu/setting/components/SpecConfig.vue';
  import { SpuSpecificationTypeEnum, UiComponentEnum } from '@/enums/spuEnum';
  import SpecBasicInfo from '@/views/spu/spu/setting/components/SpecBasicInfo.vue';

  const props = defineProps({
    // 是否为子规格项数据
    ifChild: {
      type: Boolean,
      default: false,
    },
    // 数据源
    spuConfig: {
      type: Object,
      default: () => {
        return {};
      },
    },
  });

  const specBasicInfoRef = ref(null);
  const specGroupRef = ref(null);
  // 当前组件id
  const comId = computed(() => {
    return `spuSpec${props.spuConfig.id || Math.random()}`;
  });
  // 规格数据源列表
  const specList = computed(() => {
    const { spuSpecList, childSpuSpecList } = props.spuConfig;
    return (props.ifChild ? childSpuSpecList : spuSpecList) || [];
  });
  // 移除规格项
  function handleRemoveSpecItem(index: number) {
    specList.value.splice(index, 1);
  }
  // 选择规格项业务元属性成功
  function handleChooseBizMetaAttrOk(data: any, index: number) {
    const target = data?.[0] || {};
    const { id, cnName, uiComponentCodeList } = target;
    const uniCom = uiComponentCodeList?.[0] || '';
    specList.value.splice(index, 1, {
      ...specList.value[index],
      bizMetaAttrId: id,
      displayName: cnName,
      uiComponent: uniCom || specList.value[index]?.uiComponent || '',
    });
  }
  // 选择规格值成功
  function handleChooseOptValueOk(data: any, index: number) {
    const oldOptValueList = specList.value[index]?.optValueList || [];
    const optValueList = data.map((item: any, index: number) => {
      const { id, cnName, bizMetaAttrId } = item;
      const find = oldOptValueList.find(
        (find: any) => find.bizMetaAttrId === id || find.bizMetaAttrId === bizMetaAttrId,
      );
      return (
        find || {
          sort: index + 1,
          bizMetaAttrId: id,
          displayName: cnName,
          spuSpecId: find?.spuSpecId || '',
        }
      );
    });
    specList.value.splice(index, 1, {
      ...specList.value[index],
      optValueList,
    });
  }
  // 移除规格组
  function handleRemoveGroup(index: number) {
    specList.value.splice(index, 1);
  }
  // 规格组内规格添加
  function handleAddSpecInGroup(type: SpuSpecificationTypeEnum, index: number) {
    const ifGroup = type === SpuSpecificationTypeEnum.GROUP;
    specList.value[index].childSpuSpecList.push({
      ...cloneDeep(defaultSpuSpec),
      type,
      uiComponent: ifGroup ? UiComponentEnum.GROUP : '',
    });
  }
  // 规格组关联规格值
  function handleRelevanceOprValue(data: any, spec: any) {
    spec.optValueList = data;
    // nextTick().then(() => handleSave());
  }
  // 规格组选择元属性
  function handleChooseGroupBizMetaAttr(data: any, index: number) {
    specList.value.splice(index, 1, {
      ...specList.value[index],
      ...data,
      uiComponent: data['uniCom'] || specList.value[index]?.uiComponent || '',
    });
  }

  // 拖拽相关
  onMounted(() => {
    initDrag(true);
  });
  // 保存操作
  const handleSave: any = inject('handleSave');
  // 新拖拽初始化事件
  const handleNewSortable: any = inject('handleNewSortable');
  // 拖拽实例
  const sortable = ref<any>({});
  // 拖拽模型缓存
  const sortableCache = ref<string[]>([]);
  // 初始化拖拽
  function initDrag(flag: boolean) {
    if (!flag) return;
    const tbody: HTMLElement | null = document.getElementById(comId.value);
    const has = sortableCache.value.includes(comId.value);
    if (has || !tbody) return;
    sortable.value = new Sortable(tbody, {
      animation: 150,
      forceFallback: true, // 忽略HTML5原生拖拽行为
      chosenClass: 'chosen', // 选中样式
      onEnd({ newIndex, oldIndex }) {
        if (newIndex === oldIndex) return;
        // 根据新老索引替换位置
        const cur = specList.value.splice(oldIndex, 1)[0];
        specList.value.splice(newIndex, 0, cur);
        nextTick().then(() => handleSave());
      },
      onChange() {
        // 取消页面选中（拖拽造成的覆盖选中）
        debounce(() => window.getSelection()?.empty?.(), 200);
      },
    });
    sortableCache.value.push(comId.value);
    handleNewSortable(sortable.value);
  }

  defineExpose({ specGroupRef, specBasicInfoRef });
</script>

<style scoped lang="less">
  :deep(.ant-form-item) {
    margin-bottom: 15px;
  }
</style>
